import java.awt.Point;
import java.util.Vector;

/**
 * Matrix class manager -  for the operation matrixs
 *
 */

public class Matrix {
	
	/** 
	 * Matrix class members
	 */
	private double[][] matrix = null;
	private int row;
	private int col;

	//ctor
	public Matrix(int row, int col){
		initMatrix();
		this.row = row;
		this.col = col;
		initMatrix();
	}
	
	public double[][] getMat(){return matrix;}
	/**
	 * Class for init the Matrix
	 */
	public void initMatrix(){
		matrix = new double[row][col];
		for (int i=0;i<row;i++){
			for (int j=0;j<col;j++){
				if (i==j){
					matrix[i][j] = 1;
				}else{
					matrix[i][j] = 0;
				}
			}
		}
	}
	/**
	 * copy constructor
	 */
	public Matrix(Matrix mat){
		this.row = mat.row;
		this.col = mat.col;
		matrix = new double[row][col];
		for (int i = 0; i<row; i++){
			for (int j = 0; j<col; j++){
				matrix[i][j] = mat.matrix[i][j];
			}
		}
	}

	
	/**
	 * Function for mult Scale matrix 
	 * @param a
	 * @param b
	 * Creates Scale matrix and mult this.matrix with it
	 */
	public void MultScale(double a , double b, double centerX,double centerY){
		double [][] scaleMat = new double[][]{{a,0,0},{0,b,0},{0,0,1}};
		multMatrix(scaleMat);

	}
	/**
	 * Function for mult Rotation matrix 
	 * @param theta  
	 * Creates Rotation matrix and mult this.matrix with it
	 */
	public void MultRotation(double theta){
		double radTheta = Math.toRadians(theta);
		double sin = Math.sin(radTheta);
		double cos = Math.cos(radTheta);
		double [][] rotateMat = new double[][]{{cos,sin,0},{(-1)*sin,cos,0},{0,0,1}};
		multMatrix(rotateMat);
	}
	
		/**
	 * Function for mult translate matrix 
	 * @param a
	 * @param b
	 * Creates Translation matrix and mult this.matrix with it
	 */
	public void MultTranslate(double a , double b){
		double [][] translateMat = new double[][]{{1,0,a},{0,1,b},{0,0,1}};
		multMatrix(translateMat);
	}

	
	/**
	 * Function for mult a given point with the matrix
	 * @param p - given point to mult
	 * @return the new point 
	 */
	public Point multPoint(Point p){
		Vector<Integer> res = new Vector<Integer>();
		Vector<Integer> v = new Vector<Integer>();
		v.add(p.x);
		v.add(p.y);
		v.add(1);
		//calc  matrix*Point
		for (int i=0;i<row;i++){
			double val = 0;
			for (int j=0;j<col;j++){
				val+=matrix[i][j]*v.get(j);
			}
			res.add(new Integer((int)val));
		}
		//the new point 
		return new Point(res.get(0),res.get(1));
	}
	
	/**
	 * Function that gets a matrix and mult this.matrix with the given matrix
	 * @param m
	 */
	public void multMatrix(double[][] m){
		//temp matrix for the calculation
		double[][] multMat = new double[][]{{0,0,0},{0,0,0},{0,0,0}};
		//mult the matrix
		for (int i=0;i<row;i++){
			for (int j=0;j<col;j++){
				double val = 0;
				for (int k=0;k<col;k++){
					val += m[i][k]*matrix[k][j];
					
				}
				multMat[i][j] = val;
			};
		}
		//update this.matrix with the result matrix
		for (int i=0;i<row;i++){
			for (int j=0;j<col;j++){
				matrix[i][j] = multMat[i][j];
			}
		}
	}
	
	/**
	 * return string presentation of the matrix
	 */
	public String toString(){
		StringBuilder sb = new StringBuilder();
		for (int i=0;i<row;i++){
			for (int j=0;j<col;j++){
				sb.append(matrix[i][j] + " "); 
			}
			sb.append("\n");
		}
		return sb.toString();
	}

}
